package lotus.blog.lotusblog.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import lotus.blog.lotusblog.mapper.UserMapper;
import lotus.blog.lotusblog.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Data
@ConfigurationProperties(prefix="lotus.jwt")
@Component
public class JwtUtil {
    private String secret;
    private long expire;
    private String header;
    private long refreshExpire;
    @Autowired
    UserMapper userMapper;

    /**
     * 生成token
     */
    //注意这里的sercet不是密码，而是进行三件套（salt+MD5+1024Hash）处理密码后得到的凭证
    //这里为什么要这么做，在controller中进行说明
    public String getJwtToken(String username) {
        Date date = new Date(System.currentTimeMillis() + expire);
        Algorithm algorithm = Algorithm.HMAC256(secret);    //使用密钥进ex行哈希
        // 附带username信息的token
        return JWT.create()
                .withClaim("username", username)
                .withExpiresAt(date)
                //过期时间
                .sign(algorithm);     //签名算法
    }

    /**
     * 校验token是否正确
     */
    public boolean verifyToken(String token, String username) {
        try {
            //根据密钥生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("username", username)
                    .build();
            //效验TOKEN（其实也就是比较两个token是否相同）
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 在token中获取到username信息
     */
    public String getUserClaim(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 判断是否过期
     */
    public boolean isExpire(String token){
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getExpiresAt().getTime() < System.currentTimeMillis() ;
    }
    public String refreshToken(String username){
        return getJwtToken(username);
    }
    public User getUserBytoken(HttpServletRequest request){
        String token = request.getHeader("Authorization");
        String email = getUserClaim(token);
        User queryUser = userMapper.getUserByEmail(email);
        return queryUser;
    }
}

